package com.wyix.orm;

import com.wyix.annotation.Column;
import com.wyix.annotation.Table;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class MiniORM {
    private Connection connection; // 假设已通过数据库连接池获取

    public MiniORM(Connection connection) {
        this.connection = connection;
    }

    // 通用保存方法：通过反射读取注解，动态生成 SQL
    public void save(Object entity) throws Exception {
        Class<?> entityClass = entity.getClass();
        // 1. 获取类上的 @Table 注解，确定表名
        Table tableAnnotation = entityClass.getAnnotation(Table.class);
        if (tableAnnotation == null) {
            throw new IllegalArgumentException("实体类未标记 @Table 注解");
        }
        String tableName = tableAnnotation.value();

        // 2. 获取所有字段，读取 @Column 注解，确定列名和值
        Field[] fields = entityClass.getDeclaredFields();
        StringBuilder columns = new StringBuilder();
        StringBuilder placeholders = new StringBuilder();
        Object[] values = new Object[fields.length];

        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            field.setAccessible(true); // 允许访问私有字段

            // 读取 @Column 注解获取列名
            Column columnAnnotation = field.getAnnotation(Column.class);
            if (columnAnnotation == null) {
                throw new IllegalArgumentException("字段 " + field.getName() + " 未标记 @Column 注解");
            }
            String columnName = columnAnnotation.value();

            // 获取字段值（反射调用 get 方法）
            Object value = field.get(entity);

            // 拼接 SQL 片段
            columns.append(columnName).append(i == fields.length - 1 ? "" : ", ");
            placeholders.append("?").append(i == fields.length - 1 ? "" : ", ");
            values[i] = value;
        }

        // 3. 动态生成 INSERT SQL 并执行
        String sql = String.format(
                "INSERT INTO %s (%s) VALUES (%s)",
                tableName, columns.toString(), placeholders.toString()
        );
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            for (int i = 0; i < values.length; i++) {
                pstmt.setObject(i + 1, values[i]); // 设置参数（JDBC 参数从 1 开始）
            }
            pstmt.executeUpdate();
            System.out.println("SQL 执行成功：" + sql);
        } catch (SQLException e) {
            throw new RuntimeException("数据库操作失败", e);
        }
    }
}